#pragma once

#define INITGUID
#define DIRECTINPUT_VERSION 0x0800

#include <map>
#include <list>
#include <dinput.h>
#include "IEngineSystem.h"
#include "InputComponent.h"
#include "WindowSystem.h"
#include "SystemCollection.h"

// {D946A887-7845-40bc-A5C7-505628617295}
DEFINE_GUID(INPUT_SYSTEM_GUID, 
0xd946a887, 0x7845, 0x40bc, 0xa5, 0xc7, 0x50, 0x56, 0x28, 0x61, 0x72, 0x95);

class InputSystem : public IEngineSystem
{
public:
	InputSystem(EnginePointer<SettingsManager>& settings, EnginePointer<IMessageQueue>& messages);
	~InputSystem(void);

	HRESULT Initialize(EnginePointer<SystemCollection>& systems);
	void Update(LONGLONG timeElapsed);
	void Clean();
	BOOL IsClean();
	HRESULT RegisterComponent(EnginePointer<IEngineComponent>& component);
	GUID getSystemIdentifier();
	list<GUID> getDependencies();

	AUTO_SIZE;
private:
	EnginePointer<WindowSystem> windowSystem;
	BOOL initialized;

	LPDIRECTINPUTDEVICE8 keyboardDevice;
	LPDIRECTINPUTDEVICE8 mouseDevice;
	BYTE* lastKeys;
	BYTE* currentKeys;
	map<BYTE, list<EnginePointer<InputComponent>>> downBindings;
	map<BYTE, list<EnginePointer<InputComponent>>> holdBindings;
	map<BYTE, list<EnginePointer<InputComponent>>> upBindings;
	list<EnginePointer<InputComponent>> components;

	void addDownBinding(BYTE key, EnginePointer<InputComponent> component);
	void addHoldBinding(BYTE key, EnginePointer<InputComponent> component);
	void addUpBinding(BYTE key, EnginePointer<InputComponent> component);

	HRESULT LoadGraphicsContent();
	void UnloadGraphicsContent();
};
